#include "MceTimings.h"

#define CCF_TIMING 0.241246

void MceTimings::init ( UIntVector ccf,  unsigned int repeats, PtrSize blasters)
{
	m_Blasters = blasters;
	fromCCF(ccf, repeats);
}


MceTimings::MceTimings() : m_Blasters(3), m_Timings(0)
{
}

MceTimings::MceTimings(UIntVector ccf) : m_Blasters(3), m_Timings(0)
{
	init ( ccf, 0, 3 );	
}

MceTimings::MceTimings(UIntVector ccf, unsigned int repeats) : m_Blasters(3), m_Timings(0)
{
	init ( ccf, repeats, 3 );	
}

MceTimings::MceTimings(UIntVector ccf, unsigned int repeats, PtrSize blasters) : m_Blasters(3), m_Timings(0)
{
	init ( ccf, repeats, blasters);
}

MceTimings::~MceTimings()
{
	if ( m_Timings )
		delete [] m_Timings;
}

bool MceTimings::fromCCF ( UIntVector ccf, unsigned int repeats )
{	
	if ( ccf.size() < 5 )
		return false;
	
	if ( (ccf[2] + ccf[3]) * 2 + 4 != ccf.size() )
		return false;

	// only learned thank you.
	if ( ccf[0] != 0 )
		return false;
	
	double pulseDuration = ccf[1] * CCF_TIMING;
	
	if ( m_Timings ) 
		delete [] m_Timings;

	m_Count = ( ccf[2] + ccf[3] ) * 2 + 3;
	m_Timings = new PtrSize [ m_Count ];

	
	int d = 0;
	m_Timings[0] = 0; // magic value,.. what is this?
	m_Timings[1] = 1; // magic value,.. what is this?
	m_Timings[2] = sizeof(PtrSize) * ( ( ccf[2] + ccf[3] ) * 2 ); // size of the message command following the header in bytes.
	d = 3;

	// the next parts are positive meaning send IR signal
	// negative means just wait.

	int startOffset = 4;

	for ( unsigned int i = 0; i < (ccf[2] * 2)  ; i++ )
	{	
		if ( i % 2 == 0 )
		{
			m_Timings[d] = (PtrSize)( ccf[i+startOffset] * pulseDuration );
		}
		else
		{
			m_Timings[d] = -1 * (PtrSize)( ccf[i+startOffset] * pulseDuration );
		}		
		d++;
	}

	startOffset = 4 + ( ccf[2] * 2 );
	for ( unsigned int j = 0 ; j < repeats; j++ )
	{

		for ( unsigned int i = 0 ; i < (ccf[3] * 2) ; i++)
		{
			if ( i % 2 == 0 )
			{
				m_Timings[d] = (PtrSize)( ccf[i+startOffset] * pulseDuration );
			}
			else
			{
				m_Timings[d] = -1 * (PtrSize)( ccf[i+startOffset] * pulseDuration );
			}		
			d++;
		}

	}

	m_Frequency = PtrSize( 1000000 / ( ccf[1] * CCF_TIMING ) );

	return true;

}

PtrSize * MceTimings::getTimings()
{
	return m_Timings;
}

size_t MceTimings::getCount ()
{
	return m_Count;
}

PtrSize MceTimings::getBlasters()
{
	return m_Blasters;
}

void MceTimings::setBlasters( PtrSize value )
{
	m_Blasters = value;
}

PtrSize MceTimings::getFrequency()
{
	return m_Frequency;
}